<script>
export default {
  name: 'LoginForm',
  data() {
    return {
      // 是否记住用户
      remember: false,
      // 控制按钮loading效果
      loading: false,
      // 表单组件ref实例
      loginFormRef: null,
      // 登录表单对象
      loginForm: {
        username: '',
        password: '',
      },
      // 登录表单规则对象
      loginRules: {
        username: [
          { required: true, message: '请输入用户账号', trigger: 'blur' },
        ],
        password: [
          { required: true, message: '请输入用户密码', trigger: 'blur' },
        ],
      },
    };
  },
  methods: {
    // 持久化存储checkbox勾选状态的回调函数
    persistenceRemmber() {
      try {
        // 取出勾选状态
        const remember = localStorage.getItem('remember');
        // 判断字符串是true还是false
        if (remember === 'true') {
          // 数据回显
          this.remember = true;
        } else {
          // 数据回显
          this.remember = false;
        }
      } catch (error) {
        console.log(error.message);
      }
    },
    // 持久化存储用户名和密码的回调函数
    persistenceAccount() {
      try {
        // 从本地存储中取出用户名以及密码
        const { username, password } = JSON.parse(localStorage.getItem('account'));
        // 进行数据回显
        this.loginForm.username = username;
        this.loginForm.password = password;
      } catch (error) {
        console.log(error.message);
      }
    },
    // 点击登录按钮的回调函数
    async handleLogin() {
      /*
     * 1.进行表单的兜底校验，表单兜底校验不通过则return出去不执行逻辑，校验通过派发一个action携带表单的用户名和密码去发送登录请求
     * 2.action如果+了async修饰符返回的是一个Promise对象，组件里使用try-catch捕获本次发送登录请求出现的错误(请求失败在响应拦截器中做了处理会return一个失败的Promise对象)
     * 3.发送登录请求成功了跳转首页，失败提示用户本次登录失败并且告知原因
     * validate(callback:Function(boolean, object))对整个表单进行校验的方法，参数为回调函数。
     * 该回调函数会在校验结束后被调用，并传入两个参数：是否校验成功和未通过校验的字段。(若不传入回调函数则会返回一个promise!!!)
     * */
      // 进行表单的兜底校验(返回true成功，false则失败)
      const validateResult = await this.$refs.loginFormRef.validate().catch((error) => error);
      // 校验失败提示用户
      if (!validateResult) return this.$message.error('请完善登录信息');
      // 开启按钮loading效果
      this.loading = true;
      // 判断用户是否勾选记住用户名以及密码
      if (this.remember) {
        localStorage.setItem('account', JSON.stringify(this.loginForm));
      } else {
        localStorage.removeItem('account');
      }
      try {
        // dispatch派发action发送请求
        await this.$store.dispatch('userStore/loginAction', this.loginForm);
        // 路由跳转
        this.$router.push(this.$route.query.return_url || '/');
        // 提示用户登录成功
        this.$message.success('登录成功');
      } catch (error) {
        // 登录失败
        this.$message.error(error.message);
      } finally {
        // 成功和失败都会执行finally
        this.loading = false;
      }
    },
  },
  computed: {
    rememberComputed: {
      get() {
        return this.remember;
      },
      set(value) {
        this.remember = value;
        localStorage.setItem('remember', this.remember);
      },
    },
  },
  mounted() {
    this.persistenceAccount();
    this.persistenceRemmber();
  },
};
</script>

<template>
  <el-form ref="loginFormRef" :model="loginForm" :rules="loginRules">
    <el-form-item label="账号" prop="username">
      <el-input placeholder="请输入用户账号" v-model="loginForm.username"></el-input>
    </el-form-item>
    <el-form-item label="密码" prop="password">
      <el-input type="password" show-password placeholder="请输入用户密码" v-model="loginForm.password"></el-input>
    </el-form-item>
    <el-form-item>
      <el-checkbox v-model="rememberComputed">记住我</el-checkbox>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" class="login_btn" :loading="loading" @click="handleLogin">登录</el-button>
    </el-form-item>
    <el-link type="danger" :underline="false">仅用于IT培训教学使用，为保障您的个人信息安全，请勿向平台录入任何个人敏感信息（如手机号、身份证号等）！</el-link>

    <div>
      <el-link type="danger" :underline="false">账号：demo</el-link>
    </div>
    <div>
      <el-link type="danger" :underline="false">密码：zh@hm#23</el-link>
    </div>

  </el-form>
</template>

<style scoped lang="scss">
.el-form {
  width: 350px;
}

.ant-form-item {
  display: flex;
  margin-bottom: 60px;
  flex-direction: column;
}

.ant-form-item-label label {
  font-size: 16px;
  color: #8b929d;
}

.ant-input,
.ant-input-password {
  border-radius: 8px;
}


.login_btn {
  width: 100%;
}
</style>
